home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
176-200
/
disk_183
/
fixfd
/
fixfd.asm
< prev
next >
Wrap
Assembly Source File
|
1992-05-06
|
15KB
|
724 lines
; file:FixFD.asm
;-----------------------------
; Fix FD
;-----------------------------
; A utility to convert FD files to EQU files.
;
; Copyright (c) 1988 by Peter Wyspianski
;
; Revision History
; ----------------
; 30 Dec 88 created
; 01 Jan 89 changed to use the 'dos_lib.i' file
;----------------------------------------
; Constants
null equ $00
bs equ $08
tab equ $09
lf equ $0a ; amiga eoln
cr equ $0d ; CR only
esc equ $1b
csi equ $9b ; control sequence introducer
; DOS Constants:
MODE_OLDFILE equ 1005
MODE_NEWFILE equ 1006
SIGBREAKB_CTRL_C EQU $0C
SIGBREAKB_CTRL_D EQU $0D
SIGBREAKB_CTRL_E EQU $0E
SIGBREAKB_CTRL_F EQU $0F
SIGBREAKF_CTRL_C EQU $1000
SIGBREAKF_CTRL_D EQU $2000
SIGBREAKF_CTRL_E EQU $4000
SIGBREAKF_CTRL_F EQU $8000
;**SIGBREAK_ANY equ $F000
SIGBREAK_ANY equ $1000
; Exec Base Offsets:
ThisTask EQU $114
; Task Control Structure Offsets:
TC_SIGRECVD EQU $1A
TC_SIGALLOC EQU $12
;----------------------------------------
; Includes
MACFILE "RAM:Std_Macs68k"
INCLUDE "RAM:dos_lib.i"
;----------------------------------------
; Publics
XDEF _main
XDEF Exit
;----------------------------------------
; Externals:
; from std.startup:
XREF _exit
XREF _stdin,_stdout,_SysBase,_DOSBase
;----------------------------------------
; The beginning
SECTION Main,CODE
; just a little something to brighten some file-zapper's day:
dc.b 'Be Happy!',null
cnop 0,2
;-------------------------------
; BCD_Left [18 Nov 88]
;
; - converts hex word to a string of one to five left justified BCD digits
; - string is null terminated
;
; Inputs : d0.w = hex word
; a0.l = starting address of string
; Outputs: all regs preserved
;
; Notes : - from 1 to five digits can be returned plus the zero termination
; for a total of up to six characters
; - starts by determining number of digits in the string
BCD_Left
pushm d0-d3/a0-a1
move.w #3,d2 ; # digits - 2
lea LBCDTAB,a1 ; point to ten thousands
1$ cmp.w (a1)+,d0 ; determine number of digits in result
bcc.s 2$ ; (ubge) taken if right size
dbra d2,1$ ; taken for 10K through 10
bra.s 6$ ; we have just a ones digit
2$ subq.l #2,a1 ; compensate for following pre-decrement
3$ move.w (a1)+,d1 ; d1=BCD digit weight
move.b #'0',d3 ; init digit to ASCII '0'
4$ cmp.w d1,d0 ; digit weight ? remainder
blt 5$ ; taken if done with this digit
addq.b #1,d3 ; inc BCD digit result
sub.w d1,d0 ; decrement total
bnz.s 4$ ; go for more
5$ move.b d3,(a0)+ ; stash digit
dbra d2,3$ ; next digit position
6$ or.b #'0',d0 ; form ones digit
move.b d0,(a0)+
clr.b (a0) ; form zero terminator
pullm d0-d3/a0-a1
rts
LBCDTAB dc.w 10000,1000,100,10
;----------------------------------------
; GetDec [30 Dec 88]
;
; - converts a decimal string to a hex value
;
; Inputs : a0 = ^ string
; Outputs: d0.l = value
;
; Reg Use: d1,a0-a1
;
; Calls : none
; Uses : none
;
; Notes : - Non-numeric input produces garbage (GIGO applies).
; - Excessively long strings cause wrap-around.
GetDec:
clr.l d0 ; result
1$ move.b (a0)+,d1 ; fetch next digit
bz.s 2$ ; if 'digit' is a null then all done
; here the running result is multiplied by ten:
asl.l #1,d0 ; x2
move.l d0,a1 ; save the x2 value (a1 = scratch)
asl.l #2,d0 ; x4 x8
add.l a1,d0 ; x8 + x2 = x10
; the latest 'units' digit is added to the result:
sub.b #'0',d1 ; force digit to range 0-9
add.l d1,d0 ; splice into result
bra.s 1$ ; and go for more!
2$ rts
;----------------------------------------
; PrStr [31 Dec 88] _stdout
; FPrStr [31 Dec 88] a file
;
; - sends a null terminated string to a file (_stdout)
;
; Inputs : a0 = ^string
; a1 = file handle (FPrStr only)
;
; Outputs: none
;
; Calls : Write (DOS.Library)
; Uses : _DOSBase (library base)
; _stdout
;
; Notes : exits via the call to Write
PrStr:
move.l _stdout,a1
FPrStr:
push.l a1 ; save file handle
move.l a0,a1 ; find the string length
1$ tst.b (a1)+
bnz.s 1$ ; loop until end of string
sub.l a0,a1 ; start-end+1 = len+1
sub.l #1,a1 ; fix the length
pull.l d1 ; recover file handle
move.l a0,d2 ; ^buffer
move.l a1,d3 ; length
move.l _DOSBase,a6
jmp _LVOWrite(a6) ; exit via this routine
;----------------------------------------
; ReadLn [31 Dec 88] from _stdin
; FReadLn [31 Dec 88] from a file
;
; - reads a line from a file (_stdin)
; - terminator (lf) is NOT stored
; - string is returned null-terminated
;
; Inputs : a0 = ^string buffer
; a1 = file handle (FReadLn only)
;
; Outputs: d0 = result: 1 = ok, 0 = eof, -1 = error
;
; Reg Use: d0-d3/a0-a2
;
; Calls : Read (DOS.Library)
; Uses : _DOSBase (library base)
ReadLn:
move.l _stdin,a1
FReadLn:
move.l a0,a2 ; keep ^buffer safe
move.l a1,a3 ; keep file handle safe
1$ move.l a3,d1 ; file handle
move.l a2,d2 ; ^buffer
move.l #1,d3 ; read one char
CallDOS Read
cmp.l #1,d0 ; what was returned?
bne.s 2$ ; exit if error or eof
move.b (a2)+,d1 ; fetch character and bump ^buffer
cmp.b #lf,d1 ; end of line?
bne.s 1$ ; taken if not
2$ move.b #null,-1(a2) ; null terminate the string
rts ; and exit
;----------------------------------------
; FileOpenError [31 Dec 88]
;
; - calls IoErr to get a specific error number for a failed file open.
; - prints an error message of the form:
;
; Error #xxx opening file "yyyy".
;
;
; Inputs : a0 = ^filename
; Outputs: none
;
; Reg Use: d0-d1/a0-a1
;
; Calls : IoErr (DOS.Library)
; BCD_Left
; PrStr
; Uses : _DOSBase (library base)
; BCDBuff
FileOpenError:
push.l a0 ; save ^file name
CallDOS IoErr ; must do this FIRST
push.w d0 ; save the bad news
lea BadOpenMsg,a0
jsr PrStr
pull.w d0 ; recover error number
lea BCDBuff,a0
jsr BCD_Left
lea BCDBuff,a0
jsr PrStr ; show the number
lea BadOpenMsg1,a0 ; second half of error message
jsr PrStr
pull.l a0 ; fetch ^file name
jsr PrStr
lea BadOpenMsg2,a0 ; third half of error message
jsr PrStr
rts
*----------------------------------------
* Main [30 Dec 88]
*
* here is a picture of the entry stack:
*
* 12 --- not ours!
* 8 ^argvArray pointer to argvArray
* 4 argc argument count
* sp 0 RA our return address
_main:
clr.l TheError ; default good return
move.l sp,savesp ; to ensure that we clean up on exit
pull.l ReturnAddr ; just in case we need it...
; make a pointer to our TC_SIGRECVD:
move.l _SysBase,a0 ; base of the Exec library
move.l ThisTask(a0),a0 ; ^Task Control Structure (that's us!)
lea TC_SIGRECVD(a0),a0 ; ^the flags
move.l a0,TaskSigs ; save the pointer for later
; and we're off:
lea GreetMsg,a0 ; say hello
jsr PrStr
pull.l argc ; argc (argument count)
pull.l argv ; ^argv (argument array)
move.l argc,d0 ; argv format: <name> <source> <dest>
cmp.l #3,d0 ; we need three arguments...
blt.l Help ; ...taken if 'confused user' error!
move.l argv,a0 ; fetch ^argv
move.l 4(a0),a0 ; point to first argument
move.l a0,SName ; save ^source file name
move.l argv,a0 ; fetch ^argv
move.l 8(a0),a0 ; point to second argument
move.l a0,DName ; save ^dest file name
; open the input file:
move.l SName,d1
move.l #MODE_OLDFILE,d2 ; must already exist
CallDOS Open
move.l d0,sfile ; save source file handle
bnz.s 1$ ; taken if ok
; handle problems opening the input file:
move.l SName,a0
jsr FileOpenError
move.l #30,TheError
bra.l Exit ; bye!
; open the output file:
1$ move.l DName,d1
move.l #MODE_NEWFILE,d2
CallDOS Open
move.l d0,dfile ; save dest file handle
bnz.s ScanFD ; taken if ok
; handle problems opening the output file:
move.l DName,a0
jsr FileOpenError
move.l #30,TheError
bra.l Exit2
; read lines of the input file until EOF is true:
ScanFD:
; If the output file is acutally the tube then we don't want
; line numbers cluttering the display:
move.l dfile,d1 ; output file handle
CallDOS IsInteractive
move.b d0,TubeOut ; -1 = yeah, 0 = nope
lea HeaderMsg,a0
move.l dfile,a1 ; output file handle
jsr FPrStr
move.l DName,a0
move.l dfile,a1 ; output file handle
jsr FPrStr
lea HeaderMsg1,a0
move.l dfile,a1 ; output file handle
jsr FPrStr
tst.b TubeOut ; skip screen formatting if outfile...
bnz.s 1$ ; ... is connected to the tube.
lea StatusMsg,a0
jsr PrStr
lea CursorOff,a0
jsr PrStr
1$ move.w line,d0 ; bump line number
add.w #1,d0
move.w d0,line
tst.b TubeOut ; gonna use the tube?
bnz.s 8$ ; taken if not (being used by out file)
lea BCDBuff,a0 ; convert line number to a dec string
jsr BCD_Left
lea BCDBuff,a0 ; show the line number
jsr PrStr
; This gets REAL fancy by adding one 'bs' to StrBuff for every
; non-null char in BCDBuff:
lea BCDBuff,a0
lea StrBuff,a1
2$ move.b #bs,(a1)+ ; put one in there
tst.b (a0)+ ; check for a null
bnz.s 2$ ; taken if not
move.b #null,-1(a1) ; kill the last bs and null terminate
lea StrBuff,a0 ; backup
jsr PrStr
8$ move.l TaskSigs,a0 ; see if the user hit ctrl-c thru ctrl-f
move.l (a0),d0 ; d0 = SigsRecvd
and.l #SIGBREAK_ANY,d0 ; mask all but ours
bnz.l Abort ; taken if we hit
lea StrBuff,a0 ; fetch a line from the input file
move.l sfile,a1
jsr FReadLn
tst.l d0 ; see what's up!
bz.l Exit0 ; taken if EOF
bmi.l Exit0 ; taken if error
;----------------------------------------
; determine what sort of line it is here:
;
; # = option (process further)
; A-Z,a-z,'_','.' = FD entry (strip)
;
; all others are ignored ('*',';', and anything else)
move.b StrBuff,d0 ; fetch first char
cmp.b #'#',d0 ; option?
beq 6$ ; taken if so
cmp.b #'.',d0 ; fd entry?
beq.s 3$ ; taken if so
cmp.b #'_',d0 ; fd entry?
beq.s 3$ ; taken if so
cmp.b #'A',d0 ; fd entry?
blt.l 1$ ; taken if NOT (ignore)
or.b #$20,d0 ; force to lowercase
cmp.b #'z',d0 ; fd entry?
bgt.l 1$ ; taken if NOT (ignore)
;---------------------------------------------------------------
; strip the line (scan for a space, open paren, or end of line)
; there are NO blank lines here (eliminated above):
;
3$ lea LVOMsg,a0 ; prefix the routine name with '_LVO'
move.l dfile,a1
jsr FPrStr
lea StrBuff,a0
5$ move.b (a0)+,d0 ; fetch a char and bump pointer
bz.s 4$ ; taken if end of line
cmp.b #' ',d0 ; space?
beq.s 4$ ; taken if so
cmp.b #'(',d0 ; open paren?
bne.s 5$ ; taken if so
4$ move.b #null,-1(a0) ; null-terminate right AT the 1st excess char
pea -1(a0) ; save ^end of string (for later)
lea StrBuff,a0 ; show the line
move.l dfile,a1 ; output file handle
jsr FPrStr
lea StrBuff,a0
pull.l d0 ; fetch ^end of string
;*** sub.l a0,d0 ; d0 = string len
;*** lea EQU8Msg,a0 ; <tab> <tab> equ <tab>-
;*** cmp.l #8,d0 ; seven chars or less?
;*** blt.s 44$ ; taken if so (output extra tab)
lea EQUMsg,a0 ; <tab> equ <tab>-
44$ move.l dfile,a1 ; output file handle
jsr FPrStr
move.w bias,d0 ; convert the bias to a decimal string
lea BCDBuff,a0
jsr BCD_Left
lea BCDBuff,a0
move.l dfile,a1 ; output file handle
jsr FPrStr ; show the bias
lea EQUMsg1,a0 ; finish the line off
move.l dfile,a1 ; output file handle
jsr FPrStr
move.w #6,d0 ; bump bias
add.w d0,bias
bra.l 1$ ; and go again!
;----------------------------------------
; check for the '##bias' option:
6$ move.l StrBuff+2,d0 ; fetch 4 chars (should be 'bias')
or.l #$20202020,d0 ; force to lowercase
cmp.l #'bias',d0
bne.l 1$ ; ignore if not the option
; scan for a space:
lea StrBuff+6,a0 ; skip the '##bias'
7$ move.b (a0)+,d0 ; fetch a char and bump pointer
bz.l 1$ ; taken if end of line (ignore)
cmp.b #' ',d0 ; space?
bne.s 7$ ; taken if not
; fetch and show the bias:
jsr GetDec ; a0 should be pointing at the number
move.w d0,bias ; save it
; show the 'bias = ' message:
lea BiasMsg,a0
move.l dfile,a1 ; output file handle
jsr FPrStr
move.w bias,d0 ; convert the bias to a decimal string
lea BCDBuff,a0
jsr BCD_Left
lea BCDBuff,a0
move.l dfile,a1 ; output file handle
jsr FPrStr ; show the bias
lea BiasMsg1,a0
move.l dfile,a1 ; output file handle
jsr FPrStr
bra.l 1$ ; go for another line
;-------------------------------------------
; show the help message and exit:
Help:
lea HelpMsg,a0
jsr PrStr
bra.s Exit
;-------------------------------------------
; show the 'break...' message and exit:
Abort:
lea BreakMsg,a0
jsr PrStr
bra.s ExitA
;-----------------------------
; Exit routines [30 Dec 88]
;
Exit0:
lea DoneMsg,a0
jsr PrStr
ExitA:
lea CursorOn,a0
jsr PrStr
Exit1:
move.l dfile,d1 ; close the dest file
CallDOS Close
Exit2:
move.l sfile,d1 ; close the source file
CallDOS Close
Exit:
push.l TheError ; error code
jsr _exit ; and wind it up
;----------------------------------------
; constants
SECTION Constants,DATA
GreetMsg:
dc.b lf
dc.b csi,'0;33;40m'
dc.b ' FixFD '
dc.b csi,'0;31;40m'
dc.b 'v1.0 - Copyright ',$a9
dc.b ' 1988, Peter Wyspianski',lf,lf
dc.b null
HelpMsg
dc.b ' This utility takes an ''.FD'' file and generates a set of',lf
dc.b ' EQUates that can be used by an assembler.',lf,lf
dc.b ' Parameters: source_file dest_file.',lf,lf
dc.b ' See the docs for more info! -PW',lf,lf,null
BadOpenMsg:
dc.b csi,'0;33;40m'
dc.b ' Error '
dc.b csi,'0;31;40m'
dc.b '#'
dc.b null
BadOpenMsg1:
dc.b ' opening file "',null
BadOpenMsg2:
dc.b '"',lf,lf,null
CursorOff
dc.b csi
dc.b '0 p'
dc.b null
CursorOn
dc.b csi
dc.b ' p'
dc.b null
StatusMsg:
dc.b ' Reading line '
dc.b null
DoneMsg
dc.b lf,lf
dc.b csi,'0;33;40m'
dc.b ' Finished.'
dc.b csi,'0;31;40m'
dc.b lf,lf,null
BreakMsg
dc.b lf,lf
;*** dc.b csi,'0;33;40m'
dc.b '*** BREAK'
;*** dc.b csi,'0;31;40m'
dc.b lf,lf,null
HeaderMsg
dc.b '; file:',null
HeaderMsg1
dc.b lf
dc.b ';',lf
dc.b '; generated by FixFD v1.0',lf
dc.b ';',lf
dc.b null
BiasMsg
dc.b '; Bias = ',null
BiasMsg1
dc.b lf
dc.b ';',lf
dc.b null
LVOMsg
dc.b '_LVO',null
EQU8Msg
dc.b tab
EQUMsg
dc.b tab
dc.b 'equ -'
dc.b null
EQUMsg1
dc.b lf
dc.b null
;----------------------------------------
; Uninitialized storage
SECTION Variables,BSS
TaskSigs ds.l 1 ; pointer to our TC_SIGRECVD
TheError ds.l 1 ; error return code
SName ds.l 1 ; ^source file name
DName ds.l 1 ; ^dest file name
sfile ds.l 1 ; source file handle
dfile ds.l 1 ; dest file handle
savesp ds.l 1 ; entry stack pointer
argc ds.l 1 ; argument count
argv ds.l 1 ; argument array pointer
ReturnAddr ds.l 1 ; program return address
bias ds.w 1 ; library entry bias
line ds.w 1 ; current line number
TubeOut ds.b 1 ; -1 = yes, 0 = nope
ds.b 1 ; alignment
BCDBuff ds.b 6 ; bcd string buffer
StrBuff ds.b 256 ; longest possible string